package com.atguigu.dga.common.util;

import lombok.Data;
import lombok.Getter;
import org.antlr.runtime.tree.Tree;
import org.apache.hadoop.hive.ql.lib.DefaultGraphWalker;
import org.apache.hadoop.hive.ql.lib.Dispatcher;
import org.apache.hadoop.hive.ql.lib.Node;
import org.apache.hadoop.hive.ql.parse.ASTNode;
import org.apache.hadoop.hive.ql.parse.ParseDriver;
import org.apache.hadoop.hive.ql.parse.ParseException;
import org.apache.hadoop.hive.ql.parse.SemanticException;

import java.util.Collection;
import java.util.Collections;
import java.util.Stack;

public class SqlParse {


    public static void  parse(String sql, Dispatcher dispatcher) throws  Exception {
        //1  创建一个语法数解析器
        ParseDriver parseDriver = new ParseDriver();

        //2  利用语法树解析器把sql转为语法树对象
        ASTNode astNode = parseDriver.parse(sql);

        //3  调整根节点
        ASTNode firstQueryNode =(ASTNode) astNode.getChild(0);

        //4  创建一个语法树遍历器
        DefaultGraphWalker defaultGraphWalker = new DefaultGraphWalker(dispatcher);


        //5  执行遍历
        defaultGraphWalker.startWalking(Collections.singleton(firstQueryNode) ,null);

    }

    public static void main(String[] args) throws Exception {
        String sql = "select count(1) from ods_base_log l ,ods_abc a where  l.id=a.id and   dt='2020-06-01'";
        //该sql是否包含join
        JoinDispatcher joinDispatcher = new JoinDispatcher();
        SqlParse.parse(sql,joinDispatcher);
        if(joinDispatcher.isHasJoin())  {
            System.out.println("包含join");
        }else{
            System.out.println("不包含join");
        }



    }

   static class JoinDispatcher implements Dispatcher{

        @Getter
        private boolean hasJoin=false;

        @Override
        public Object dispatch(Node nd, Stack<Node> stack, Object... nodeOutputs) throws SemanticException {
            ASTNode astNode= (ASTNode) nd;
            System.out.println("astNode = " + astNode.getText());
            if("TOK_JOIN".equals(astNode.getText())){
                hasJoin=true;
            }
            return null;
        }
    }

}
